combit List & Label 29 - .NET Hilfe
Einführung in die Programmierung / Weitere wichtige Konzepte / Parametrisierbare Datenquellen nutzen
In diesem Thema
    Parametrisierbare Datenquellen nutzen
    In diesem Thema

    Einstieg

    Um effektiv und schnell List & Label an die gewünschten Datenquellen zu binden, kommen die Datenprovider zum Einsatz. Doch meist ist es nicht gewünscht, dass immer alle Daten in einem Bericht zur Verfügung stehen, sondern es sollen bereits vorab bestimmten Vorselektionen definiert werden. Das kann man auf verschiedene Arten erreichen:

    Man filtert bereits die Daten, die im verwendeten Datenprovider verwendet werden. Das hat aber den entscheidenden Nachteil, dass dabei eben nur die Daten im Datenprovider für einen Bericht verwendet werden können, was aber oft auch mit dem Hintergrund eines Berechtigungssystems der Anwendung verwendet werden kann - es können nur Daten im Bericht verwendet werden, die auch dort vorhanden sind.

    Aber oft besteht auch die Anforderung, dass nicht unbedingt die Anwendung bzw. der Entwickler entscheiden soll, welche Daten in einem Bericht vorhanden sein sollen, sondern die Anwender oder die entsprechende Fachabteilung, die den Bericht im Designer erstellt. So kann dort direkt mit Hilfe von Daten-/Projekfilter oder Berichtsparametern für die notwendige Filterung im Bericht gesorgt werden. Dabei wird die Filterung meist direkt schon automatisch im Datenprovider angewendet und ist entsprechend auf die Datenquelle selbst performant und nativ umgesetzt. Am Beispiel für eine vereinfachte Microsoft SQL Datenbank-Abfrage mit dem SqlConnectionDataProvider würde das ungefähr so aussehen - die tatsächlichen Abfrage sind selbstverständlich gegen SQL-Injection geschützt und die folgenden Statements dienen nur zur Veranschaulichung:

     

    Wenn einfach nur die Tabelle "Customers" im Bericht verwendet wird, würde der Datenprovider die folgende Abfrage nativ an den SQL Server schicken und ausführen lassen und List & Label würde dann das ResultSet in der Tabelle abbilden:

    SELECT * FROM "Customers"
    

    Kommt nun aber für die Tabelle "Customers" im Designer noch ein Datenfilter (auch in Kombination mit einem selbst erstellten Berichtsparameter) hinzu, würde nun List & Label nicht die identische Abfrage wie oben ausführen und das RestultSet dann selbst manuell auf "ALFKI" filtern. Sonst würde jeder zurück gelieferte Datensatz wird auf "ALFKI" überprüft und entsprechend verworfen oder ausgegeben werden, was vergleichsweise langsam wäre. An dieser Stelle sind die meisten Datenprovider soweit optimiert, dass diese Filterungen nativ auf dem Zielsystem ausgeführt werden, was in diesem Beispiel direkt mit dieser Abfrage endet:

    SELECT * FROM "Customers" WHERE "Cusomters.ID" = "ALFKI"
    

    Das ResultSet enthält ausschließlich die Kunden, die dem Filter entsprechen - ohne das List & Label selbst zur Laufzeit selbst vorher noch filtern müsste.

     

    Mit Hilfe von parametrisierbaren Datenquellen kann die Kombination von Parametern für die Datenquelle und Berichtsparametern im Designer sehr einfach und effektiv umgesetzt werden. So werden automatisch durch den Datenprovider die Berichtsparameter erstellt, die für eine korrekte Verwendung erforderlich sind. Dazu muss der verwendete Datenprovider variable Parameter unterstützen, die über eine spezielle Syntax konfiguriert werden können.

     

    Aufbau der Syntax für die Parameter

    Dabei muss ein bestimmtes Muster eingehalten werden. Entsprechende Parameter werden durch doppelte geschweifte Klammern definiert - "{{" für den Start eines Parameters und "}}" für das Ende des Parameters. Der Aufbau entspricht dann <FELDNAME>=<VORBELEGUNG> - Beispiel: {{CustomerID=ALFKI}}

    Darüber hinaus können zusätzliche Optionen für den Parameter definiert werden, die von der eigentlichen Parameter-Definition mit einem Pipe-Zeichen getrennt angegeben werden können: 

    Syntax: <FELDNAME>=<VORBELEGUNG>|<OPTION>

    Beispiel: {{CustomerID=ALFKI|choices=ALFKI,ANATR,ANTON,AROUT}}

     

    Dabei können auch mehrere Optionen kombiniert werden: 

    Syntax: <FELDNAME>=<VORBELEGUNG>|<OPTION1|<OPTION2>

    Beispiel: {{CustomerID=ALFKI|choices=ALFKI,ANATR,ANTON,AROUT|multiselect=true}}

     

    Option Bedeutung/Anforderung Beispiel
    format Erlaubt nur numerische Werte. {{CustomerID=123|format=number}}
    choices Erlaubt nur vordefinierte Werte auszuwählen. {{Country=US|choices=US,CA,GB}}
    choicesfield Die Werte für die Auswahl basieren auf einem Feld aus der Datenquelle und werden nicht manuell vordefiniert. {{Country=US|choicesfield=countries.code}}
    multiselect Definiert, ob eine Mehrfachauswahl der Werte möglich sein soll. {{Country=US|choices=US,CA,GB|multiselect=true}}
    hidden Der Parameter wird nicht als sichtbarer Berichtsparameter angezeigt, was für Drilldown Berichte hilfreich sein kann. {{Country=US|hidden=true}}
    displayformula Ermöglicht die Verwendung von ID-Werten für den Parameter selbst, während eine benutzerfreundliche Ersetzung angezeigt wird. {{CustomerID=123|format=number|displayvalue=Kundennummer}}

     

    Praxisbeispiele anhand verschiedener Datenprovider

    Der Artikel Schöner Filtern mit parametrisierbaren Datenquellen enthält weitere illustrierte Beispiele zu diesem Thema. Im folgenden werden Code-Snippets für dein Einsatz im eigenen Source-Code gezeigt.

     

    Webservices/REST APIs

    Mit dem JsonDataProvider kann über die URL bestimmt werden, was an Daten abgeholt werden soll. So können die Bestellungen aller Kunden definiert werden, die als "Kundennummer" angezeigt werden:

    ...
    string parameter = "{{CustomerId=123|choicesfield=CustomerId|displayformula=Kundennummer|multiselection=true}}";
    string url = String.Format("http://example.net/api/customers/{0}/orders", parameter);
    JsonDataProvider jsonData = new JsonDataProvider(url);
    ...
    
    ...
    Dim parameter As String = "{{CustomerId=123|choicesfield=CustomerId|displayformula=Kundennummer|multiselection=true}}"
    Dim url As String = String.Format("http://example.net/api/customers/{0}/orders", parameter)
    Dim jsonData As JsonDataProvider = New JsonDataProvider(url)
    ...
    

    Aber natürlich kann diese Syntax dabei auch auf andere Datenprovider wie XmlDataProvider und RestDataProvider angewendet werden.

     

    SQL-Abfrage mit Stored Procedures

    Ein Berichtsparameter "Country" wird im Rahmen einer Stored Procedure definiert und so dem DbCommandSetDataProvider übergeben, damit die Kunden anhand des Landes gefiltert werden können:

    ...
    OleDbCommand cmd = new OleDbCommand("SELECT * FROM Customers WHERE Customers.Country=?", conn);
    
    OleDbParameter param = new OleDbParameter("Country", OleDbType.VarChar, 50);
    param.Value = "{{Country=Germany|choicesfield=Customers.Country}}";
    cmd.Parameters.Add(param);
    
    DbCommandSetDataProvider prov = new DbCommandSetDataProvider();
    prov.AddCommand(cmd, "Customers", "[{0}]", null);
    ...
    
    ...
    Dim cmd As OleDbCommand = New OleDbCommand("SELECT * FROM Customers WHERE Customers.Country=?", conn)
    
    Dim param As OleDbParameter = New OleDbParameter("Country", OleDbType.VarChar, 50)
    param.Value = "{{Country=Germany|choicesfield=Customers.Country}}"
    cmd.Parameters.Add(param)
    
    Dim prov As DbCommandSetDataProvider = New DbCommandSetDataProvider()
    prov.AddCommand(cmd, "Customers", "[{0}]", Nothing)
    ...
    

     

    Excel

    Über den Datenprovider XlsDataProvider kann auf eine Excel-Datei als Datenquelle zugegriffen werden. Soll die Excel-Datei nun aber variabel im Bericht selbst über den Berichtsparameter bestimmt werden können, so würde man den Datenprovider wie folgt definieren können - es wird ein Berichtparameter "Year" mit dem Wert "2025" erstellt, der als Auswahl noch zusätzlich "2024" und "2023" bereithält und in der Folge auf einen passenden Excel-Dateinamen zeigt - "\\FileServer\RawData\2025.xlsx":

    ...
    string parameter = "{{Year=2018|choices=2023,2024,2025}}";
    string excelFileName = string.Format(@"\\FileServer\RawData\{0}.xlsx", parameter);
    XlsDataProvider excelData = new XlsDataProvider(excelFileName, firstRowContainsColumnNames);
    ...
    
    ...
    Dim parameter As String = "{{Year=2018|choices=2023,2024,2025}}"
    Dim excelFileName As String = String.Format("\\FileServer\RawData\{0}.xlsx", parameter)
    Dim excelData As XlsDataProvider = New XlsDataProvider(excelFileName, firstRowContainsColumnNames)
    ...